#include <stdio.h>

#define UNITY_INCLUDE_CONFIG_H
#include "unity.h"
#include "nolock_queue.h"

void setUp(void)
{}
void tearDown(void)
{}

void test_queue_create(void)
{
    queue_nolock_t *queue = NULL;

    queue = queue_nolock_create(8);
    TEST_ASSERT_NOT_NULL(queue);
    queue_nolock_destroy(queue);

    queue = queue_nolock_create(0);
    TEST_ASSERT_NULL(queue);
    queue_nolock_destroy(queue);

    queue = queue_nolock_create(-2); // OK, because the type of param is uint8_t
    TEST_ASSERT_NOT_NULL(queue);
    queue_nolock_destroy(queue);
}

void test_queue_empty_and_full(void)
{
    int i = 0;
    void *ptr = &i;
    queue_nolock_t *queue = NULL;

    queue = queue_nolock_create(8);
    TEST_ASSERT_NOT_NULL(queue);

    TEST_ASSERT_TRUE(queue_nolock_empty(queue));
    TEST_ASSERT_FALSE(queue_nolock_full(queue));
    TEST_ASSERT_EQUAL_INT(0, queue_nolock_size(queue));

    for(i = 0; i < 8; i++)
        TEST_ASSERT_EQUAL_INT(0, queue_nolock_push(queue, ptr + i));

    for(i = 0; i < 8; i++)
        TEST_ASSERT_EQUAL_INT(-1, queue_nolock_push(queue, ptr + i));

    TEST_ASSERT_TRUE(queue_nolock_full(queue));
    TEST_ASSERT_FALSE(queue_nolock_empty(queue));
    TEST_ASSERT_EQUAL_INT(8, queue_nolock_size(queue));

    queue_nolock_destroy(queue);
}

void test_queue_use(void)
{
    int i = 0;
    void *ptr = &i;
    queue_nolock_t *queue = NULL;

    queue = queue_nolock_create(8);

    TEST_ASSERT_NOT_NULL(queue);

    TEST_ASSERT_TRUE(queue_nolock_empty(queue));
    TEST_ASSERT_FALSE(queue_nolock_full(queue));
    TEST_ASSERT_EQUAL_INT(0, queue_nolock_size(queue));

    for(i = 0; i < 3; i++)
        TEST_ASSERT_EQUAL_INT(0, queue_nolock_push(queue, ptr + i));

    TEST_ASSERT_FALSE(queue_nolock_empty(queue));
    TEST_ASSERT_FALSE(queue_nolock_full(queue));
    TEST_ASSERT_EQUAL_INT(3, queue_nolock_size(queue));
 
    TEST_ASSERT_EQUAL_PTR(ptr, queue_nolock_pop(queue));

    TEST_ASSERT_FALSE(queue_nolock_empty(queue));
    TEST_ASSERT_FALSE(queue_nolock_full(queue));
    TEST_ASSERT_EQUAL_INT(2, queue_nolock_size(queue));

    // insert full
    for(; i < 9; i++)
        TEST_ASSERT_EQUAL_INT(0, queue_nolock_push(queue, ptr + i));

    // will filed because full
    TEST_ASSERT_EQUAL_INT(-1, queue_nolock_push(queue, ptr + i));

    TEST_ASSERT_FALSE(queue_nolock_empty(queue));
    TEST_ASSERT_TRUE(queue_nolock_full(queue));
    TEST_ASSERT_EQUAL_INT(8, queue_nolock_size(queue));

    TEST_ASSERT_EQUAL_PTR(ptr + 1, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 2, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 3, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 4, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 5, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 6, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 7, queue_nolock_pop(queue));
    TEST_ASSERT_EQUAL_PTR(ptr + 8, queue_nolock_pop(queue));

    TEST_ASSERT_TRUE(queue_nolock_empty(queue));
    TEST_ASSERT_FALSE(queue_nolock_full(queue));
    TEST_ASSERT_NULL(queue_nolock_pop(queue));
    
    queue_nolock_destroy(queue);
}

